package epoch.game.core.common;

/**
 * 通用唯一id
 * 
 * @author will
 * @date 2015年6月15日 下午3:48:36
 */
public class CommonUid {

	private static final Object obj = new Object();
	private static int timeepoch = 1509076038;
	private static int lastTimeStamp = (int) (System.currentTimeMillis() / 1000L) - timeepoch;
	private static int sequence = 0;
	private static int sequenceBits = 10; //seq.len
	private static int sequenceMax = 1023;
	private static int serverParam = 0;// 服务器参数
	private static int serverParamBits = sequenceBits + 24;
	private static int timeStamp = 0;

	public static void initParam(int param) {
		CommonUid.serverParam = param;
		sequenceMax = ((int)Math.pow(2, sequenceBits));
	}

	/**
	 * 获得唯一id
	 * 
	 * <pre>
	 * |---------timestap*32--------------|-p*7---|------s*13----|----seq*12---|64bit
	 * |---------timestap*30------------|-p*6--|-----s*13-----|-n*5-|--seq*10--|64bit
	 * 时间范围34年   
	 * 平台范围127 
	 * 服务器id范围8091 
	 * 服务节点id范围31
	 * 平均每秒生成个数范围1024
	 * </pre>
	 * 
	 * @return
	 */
	public static final long getId() {
		timeStamp = ((int) (System.currentTimeMillis() / 1000)) - timeepoch;
		synchronized (obj) {
			if (timeStamp > lastTimeStamp) {
				lastTimeStamp = timeStamp;
				sequence = 1;
			} else {
				sequence += 1;
				if (sequence >= sequenceMax) {
					sequence = 0;
					lastTimeStamp += 1L;
				}
			}
			return (lastTimeStamp & 0xFFFFFFFFFFFFFFFFL) << serverParamBits | (serverParam & 0xFFFFFFFFFFFFFFFFL) << sequenceBits | sequence;
		}
	}
}